package service

import (
	ClickHouse "gin/database"
)

type StepParent struct {
}

type Step struct {
	Id    int64  `json:"id"`
	Name  string `json:"name"`
	Code  string `json:"code"`
	Color string `json:"color"`
}

type StepRelation struct {
	Step
	ParentId int64 `json:"parent_id"`
}

type StepWithParent struct {
	Step
	Parent []*StepWithParent `json:"parent"`
}

type StepParentResItem struct {
	Step
	Level int
}

// 查询工序上级
func findParent(stepParentMap map[int64]*StepWithParent, findIdList []int64, parent *[]StepParentResItem, level int, maxLevel int) {

	if maxLevel > 0 && level == maxLevel || len(findIdList) == 0 {
		return
	}
	var nextFindIdList = make([]int64, 0)

	for _, i := range findIdList {
		if _, ok := stepParentMap[i]; !ok {
			continue
		}
		if len(stepParentMap[i].Parent) > 0 {
			for _, withParent := range stepParentMap[i].Parent {
				*parent = append(*parent, StepParentResItem{
					Step: Step{
						Id:    withParent.Id,
						Name:  withParent.Name,
						Code:  withParent.Code,
						Color: withParent.Color,
					},
					Level: level,
				})
				nextFindIdList = append(nextFindIdList, withParent.Id)
			}
		}
	}
	if len(nextFindIdList) > 0 {
		findParent(stepParentMap, nextFindIdList, parent, level+1, maxLevel)
	}
}

// getStepUpstreamRelationData 获得工序关联数据
func getStepUpstreamRelationData(projectTemplateId int64) (res []StepRelation, err error) {
	err = ClickHouse.DB.Table("step s").Joins("LEFT JOIN step_upstream su ON su.step_id = s.id and su.project_template_id = ?", projectTemplateId).
		Select("s.id as id,s.name as name,s.code as code,if(su.id is null, 0, simpleJSONExtractInt(su.config, 'step_id')) as parent_id").
		Find(&res).
		Error
	return
}

// getStepWithParentMap 获得一个包含父级关系的工序map
func getStepWithParentMap(projectTemplateId int64) (res map[int64]*StepWithParent, err error) {
	stepRelationList, err := getStepUpstreamRelationData(projectTemplateId)
	if err != nil {
		return
	}

	var stepMap = make(map[int64]bool, 0)
	var stepWithParentList = make([]StepWithParent, 0)
	res = make(map[int64]*StepWithParent)

	for _, s := range stepRelationList {
		if _, ok := stepMap[s.Id]; !ok {
			stepMap[s.Id] = true
			stepWithParentList = append(stepWithParentList, StepWithParent{
				Step: Step{
					Id:    s.Id,
					Name:  s.Name,
					Code:  s.Code,
					Color: s.Color,
				},
			})
		}
	}

	// 创建一个stepList的 map reference
	for i, v := range stepWithParentList {
		res[v.Id] = &stepWithParentList[i]
	}

	// 关联父级关系
	for _, s := range stepRelationList {
		if s.ParentId > 0 {
			res[s.Id].Parent = append(res[s.Id].Parent, res[s.ParentId])
		}
	}
	return
}

// GetStepParents 查询单个工序的所有上游
func GetStepParents(projectTemplateId int64, stepId int64) (res []StepParentResItem, err error) {
	stepWithParentRelation, err := getStepWithParentMap(projectTemplateId)
	if err != nil {
		return
	}
	findParent(stepWithParentRelation, []int64{stepId}, &res, 0, 30)
	return
}

// GetStepParents 查询单个工序的所有上游
func GetStepsParents(projectTemplateId int64, stepIdList []int64, maxLevel int) (res map[int64][]Step, err error) {
	stepWithParentRelation, err := getStepWithParentMap(projectTemplateId)
	if err != nil {
		return
	}
	res = make(map[int64][]Step, 0)
	for _, i := range stepIdList {
		var parentMap = make(map[int64]bool, 0)
		var stepParentsResult = make([]StepParentResItem, 0)
		findParent(stepWithParentRelation, []int64{i}, &stepParentsResult, 0, maxLevel)
		var parentStepList = make([]Step, 0)
		for _, item := range stepParentsResult {
			if ok, _ := parentMap[item.Id]; !ok {
				parentStepList = append(parentStepList, Step{
					Id:    item.Id,
					Name:  item.Name,
					Code:  item.Code,
					Color: item.Color,
				})
				parentMap[item.Id] = true
			}
		}
		res[i] = parentStepList
	}

	return
}
